﻿#pragma once
#ifndef WROBSERVERS_H
#define WROBSERVERS_H

#include "../WRBasics.h"

#include <QMutex>
#include <QMutexLocker>

//表示观察者集合。
template <class T> class WRObservers
{
    Q_DISABLE_COPY(WRObservers)

public:
    //定义观察者。
    typedef T* Observer;

protected:
    //元素集
    Observer* m_array;
    //元素量
    WRu m_count;
    //互斥体
    mutable QMutex m_mutex;

protected:
    //当指定的观察者添加前调用此方法。
    virtual void onAdding(Observer)
    {
        //add code here
    }
    //当指定的观察者添加后调用此方法。
    virtual void onAdded(Observer)
    {
        //add code here
    }

    //当指定的观察者移除前调用此方法。
    virtual void onRemoving(Observer)
    {
        //add code here
    }
    //当指定的观察者移除后调用此方法。
    virtual void onRemoved(Observer)
    {
        //add code here
    }

    //当清除所有观察者前调用此方法。
    virtual void onClearing(void)
    {
        //add code here
    }
    //当清除所有观察者后调用此方法。
    virtual void onCleared(void)
    {
        //add code here
    }

public:
    //初始化一个新的观察者集合对象。
    WRObservers(void) : m_array(0), m_count(0)
    {
        //add code here
    }
    //删除观察者集合所占用的相关资源。
    virtual ~WRObservers(void)
    {
        if (m_count > 0)
        {
            delete[] m_array;
            m_array = 0;
            m_count = 0;
        }
    }

    //获取观察者数量。
    WRu count(void)
    {
        return m_count;
    }
    //添加指定的观察者。
    void add(Observer observer)
    {
        QMutexLocker lock(&m_mutex);
        if (observer)
        {
            for(WRu i = 0; i < m_count; ++i)
            {
                if (m_array[i] == observer)
                {
                    return;
                }
            }

            this->onAdding(observer);

            WRu newCount = m_count + 1;
            Observer* newArray = new Observer[newCount];
            WRu oldCount = m_count;
            Observer* oldArray = m_array;
            for(WRu i = 0; i < oldCount; ++i)
            {
                newArray[i] = oldArray[i];
            }
            newArray[oldCount] = observer;
            m_array = newArray;
            m_count = newCount;
            if (oldCount > 0)
            {
                delete[] oldArray;
            }

            this->onAdded(observer);
        }
    }
    //移除指定的观察者。
    bool remove(Observer observer)
    {
        QMutexLocker lock(&m_mutex);
        if (observer)
        {
            for(WRu i = 0; i < m_count; ++i)
            {
                if (m_array[i] == observer)
                {
                    this->onRemoving(observer);

                    WRu newCount = m_count - 1;
                    Observer* newArray = 0;
                    Observer* oldArray = m_array;
                    if (newCount)
                    {
                        newArray = new Observer[newCount];
                        for(WRu j = 0; j < i; ++j)
                        {
                            newArray[j] = oldArray[j];
                        }
                        for(WRu j = i + 1; j < m_count; ++j)
                        {
                            newArray[j - 1] = oldArray[j];
                        }
                    }
                    m_array = newArray;
                    m_count = newCount;
                    delete[] oldArray;

                    this->onRemoved(observer);

                    return true;
                }
            }
        }
        return false;
    }
    //清除所有的观察者。
    void clear(void)
    {
        QMutexLocker lock(&m_mutex);
        if (m_count)
        {
            this->onClearing();

            delete[] m_array;
            m_array = 0;
            m_count = 0;

            this->onCleared();
        }
    }
};

#endif // WROBSERVERS_H
